package io.novafoundation.nova.core_db.dao

import androidx.test.ext.junit.runners.AndroidJUnit4
import io.novafoundation.nova.core_db.AppDatabase
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertArrayEquals
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotEquals
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith

private const val CHAIN_ID = "1"

@RunWith(AndroidJUnit4::class)
class MetaAccountDaoTest : DaoTest<MetaAccountDao>(AppDatabase::metaAccountDao) {

    private val chainDao by dao<ChainDao>()

    @Before
    fun insertChain() = runBlocking {
        chainDao.addChain(createTestChain(id = CHAIN_ID))
    }

    @Test
    fun shouldInsertMetaAccount() {
        runBlocking {
            dao.insertMetaAccount(testMetaAccount())
            dao.insertMetaAccount(testMetaAccount())

            val accountsFromDb = dao.getMetaAccounts()

            assertEquals(2, accountsFromDb.size)

            val isIdAutoGenerated = accountsFromDb.withIndex().all { (index, account) ->
                account.id == index + 1L
            }

            assertTrue("Id should be autogenerated", isIdAutoGenerated)
        }
    }

    @Test
    fun shouldInsertAndRetrieveChainAccounts() {
        runBlocking {
            val metaId = dao.insertMetaAccount(testMetaAccount())

            assertNotEquals(-1, metaId)

            dao.insertChainAccount(testChainAccount(metaId, CHAIN_ID))

            val joinedMetaAccountInfo = dao.getJoinedMetaAccountInfo(metaId)

            assertEquals(1, joinedMetaAccountInfo.chainAccounts.size)
        }
    }

    @Test
    fun shouldReplaceChainAccounts() {
        runBlocking {
            val metaId = dao.insertMetaAccount(testMetaAccount())

            val newAccountId = byteArrayOf(1)

            dao.insertChainAccount(testChainAccount(metaId, CHAIN_ID, accountId = byteArrayOf(0)))
            dao.insertChainAccount(testChainAccount(metaId, CHAIN_ID, accountId = newAccountId))

            val chainAccounts = dao.getJoinedMetaAccountInfo(metaId).chainAccounts

            assertEquals(1, chainAccounts.size)
            assertArrayEquals(newAccountId, chainAccounts.single().accountId)
        }
    }
}
